#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>

using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->imgFileName->setText("image1.jpg");
}

MainWindow::~MainWindow()
{
    delete ui;
}

Mat MainWindow::getSrcImg()
{
    Mat sourceImg;
    sourceImg = imread(ui->imgFileName->text().toStdString(), CV_LOAD_IMAGE_GRAYSCALE);
    if(!sourceImg.data) {
        cout << "error in reading image" << endl;
        return Mat();
    }

    Mat sourceImg2;
    sourceImg.convertTo(sourceImg2, CV_8UC1);
    return sourceImg2;
}

void MainWindow::on_pushButton_clicked()
{
    //show keypoints

    Mat sourceImg = getSrcImg();
    if (sourceImg.empty()) return;

    vector<KeyPoint> keypoints;
    SurfFeatureDetector detector(800);
    detector.detect(sourceImg, keypoints);
    Mat img_keypoints;
    drawKeypoints( sourceImg, keypoints, img_keypoints, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
    namedWindow("surf", CV_WINDOW_NORMAL);
    Mat img_keypoints2;
    cv::resize(img_keypoints, img_keypoints2, Size(img_keypoints.cols*2, img_keypoints.rows*2));
    imshow("surf", img_keypoints2);
}

void MainWindow::on_pushButton_2_clicked()
{
    //show keypoints
    Mat sourceImg = getSrcImg();
    if (sourceImg.empty()) return;

    vector<KeyPoint> keypoints;
    SiftFeatureDetector detector;
    detector.detect(sourceImg, keypoints);
    Mat img_keypoints;
    drawKeypoints( sourceImg, keypoints, img_keypoints, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
    namedWindow("sift", CV_WINDOW_NORMAL);
    Mat img_keypoints2;
    cv::resize(img_keypoints, img_keypoints2, Size(img_keypoints.cols*2, img_keypoints.rows*2));
    imshow("sift", img_keypoints2);
}

void MainWindow::on_loadImgButton_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(this,
         tr("Open Image"), ui->imgFileName->text(), tr("Image Files (*)"));
    if (!fileName.isEmpty())
        ui->imgFileName->setText(fileName);

}

void MainWindow::on_harrisCornerButton_clicked()
{
    Mat sourceImg = getSrcImg();
    if (sourceImg.empty()) return;

    int blockSize = 2;
    int apertureSize = 3;
    double k = 0.04;
    Mat dst, dst_norm, dst_norm_scaled;
    dst = Mat::zeros( sourceImg.size(), CV_32FC1 );
    cornerHarris(sourceImg, dst, blockSize, apertureSize, k);

    normalize( dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );
    convertScaleAbs( dst_norm, dst_norm_scaled );

    int thresh = 200;
    for( int j = 0; j < dst_norm.rows ; j++ )
         { for( int i = 0; i < dst_norm.cols; i++ )
              {
                if( (int) dst_norm.at<float>(j,i) > thresh )
                  {
                  circle( dst_norm_scaled, Point( i, j ), 5,  Scalar(0), 2, 8, 0 );
                  }
              }
         }

    /// Showing the result
    namedWindow( "Harris Corner", CV_WINDOW_AUTOSIZE );
    imshow( "Harris Corner", dst_norm_scaled );
    //imshow("Harris Corner", dst_norm);
}

void MainWindow::on_shiCornerButton_clicked()
{
    //show keypoints
    Mat sourceImg = getSrcImg();
    if (sourceImg.empty()) return;

    vector<Point2f> corners;
    double qualityLevel = 0.01;
    double minDistance = 10;
    int blockSize = 3;
    bool useHarrisDetector = false;
    double k = 0.04;

    int maxCorners = 400;
    RNG rng(1234);

    /// Copy the source image
    Mat copy;
    copy = sourceImg.clone();

    /// Apply corner detection
    goodFeaturesToTrack( sourceImg,
                         corners,
                         maxCorners,
                         qualityLevel,
                         minDistance,
                         Mat(),
                         blockSize,
                         useHarrisDetector,
                         k );


    /// Draw corners detected
    cout<<"** Number of corners detected: "<<corners.size()<<endl;
    int r = 4;
    for( uint i = 0; i < corners.size(); i++ ){
        circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255),
                                          rng.uniform(0,255)), -1, 8, 0 );
    }

    /// Show what you got
    namedWindow( "Shi Corner", CV_WINDOW_AUTOSIZE );
    imshow( "Shi Corner", copy );
}
